﻿using Rhino.Geometry;
using ArchiToolkit.Grasshopper;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using CGAL.Grasshopper.Types;

namespace CGAL.Grasshopper.Wrapper;

internal static class ExtrudeSkeleton
{
    static double Tolerance => Rhino.RhinoDoc.ActiveDoc.ModelAbsoluteTolerance;

    [DocObj]
    [ObjNames("ExtrudeSkeleton", "ESB", "根据基坑边缘挤出")]
    public static Mesh ExtrudeSkeletonBrep(List<PointArray> polygon, List<DoubleArray> angles,double height)
    {
        var doubleList = new List<double>();
        var countList = new List<ulong>();
        
        foreach (var points in polygon)
        {
            countList.Add((ulong)points.Value.Length);
            foreach (var point in points.Value)
            {
                doubleList.Add(point.X);
                doubleList.Add(point.Y);
            }
        }

        var meshArray = IntPtr.Zero;
        var faceCount = IntPtr.Zero;

        UnsafeNativeMethods.ExtrudeSkeleton(
            doubleList.ToArray(), countList.ToArray(), (ulong)polygon.Count,
            angles.SelectMany(i => i.Value).ToArray(),
            height,
            ref meshArray, ref faceCount
        );

        var result = new Mesh();

        var polygonCount = Marshal.ReadInt32(faceCount);

        var pointsArray = new double[polygonCount * 9];
        Marshal.Copy(meshArray, pointsArray, 0, polygonCount * 9);

        for (var i = 0; i < polygonCount; i++)
        {
            var v1 = result.Vertices.Add(pointsArray[9 * i + 0], pointsArray[9 * i + 1], pointsArray[9 * i + 2]);
            var v2 = result.Vertices.Add(pointsArray[9 * i + 3], pointsArray[9 * i + 4], pointsArray[9 * i + 5]);
            var v3 = result.Vertices.Add(pointsArray[9 * i + 6], pointsArray[9 * i + 7], pointsArray[9 * i + 8]);
            result.Faces.AddFace(v1, v2, v3);
        }

        UnsafeNativeMethods.ReleaseDoubleArray(meshArray);
        UnsafeNativeMethods.ReleaseInt(faceCount);

        return result;
    }

    
}
